package com.funsport.config;

import com.funsport.security.JwtAuthenticationFilter;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

/**
 * Spring Security 配置
 * 使用Spring Boot 2.2.5兼容的配置方式
 *
 * @author Fun-Sport Team
 */
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@RequiredArgsConstructor
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private final JwtAuthenticationFilter jwtAuthenticationFilter;

    /**
     * 密码编码器
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    /**
     * Security HTTP配置
     * 注意：由于配置了 context-path=/api，所以实际访问路径为 /api/xxx
     * 但是 antMatchers 匹配的是去掉 context-path 后的路径，即 /xxx
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                // 禁用CSRF（因为使用JWT）
                .csrf().disable()
                
                // 禁用Session（使用JWT无状态认证）
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                
                .and()
                // 配置请求授权
                .authorizeRequests()
                
                // 公开接口（无需认证）
                // 注意：这里的路径是去掉 context-path 后的路径
                .antMatchers(
                        "/mobile/auth/**",           // 移动端认证接口
                        "/mobile/club/list",         // 移动端俱乐部列表（公开）
                        "/mobile/club/{id}",         // 移动端俱乐部详情（公开）
                        "/mobile/event/list",        // 移动端活动列表（公开）
                        "/mobile/event/{id}",        // 移动端活动详情（公开）
                        "/mobile/venue/list",        // 移动端场地列表（公开）
                        "/mobile/venue/{id}",        // 移动端场地详情（公开）
                        "/mobile/stats/**",          // 移动端统计接口（公开）
                        "/web/auth/**",              // Web端认证接口
                        "/swagger-ui.html",          // Swagger UI (旧版)
                        "/swagger-ui/**",            // Swagger UI (新版)
                        "/swagger-ui/index.html",    // Swagger UI 首页
                        "/v3/api-docs",              // Swagger API文档
                        "/v3/api-docs/**",           // Swagger API文档
                        "/swagger-resources/**",     // Swagger资源
                        "/webjars/**",               // Webjars
                        "/doc.html",                 // Knife4j文档
                        "/actuator/**",              // Spring Boot Actuator
                        "/druid/**"                  // Druid监控
                ).permitAll()
                
                // Web管理端接口（需要认证，具体权限由方法级别@PreAuthorize控制）
                .antMatchers("/web/**")
                .authenticated()
                
                // 移动端接口（需要认证）
                .antMatchers("/mobile/**")
                .authenticated()
                
                // 其他所有请求都需要认证
                .anyRequest().authenticated()
                
                .and()
                // 添加JWT过滤器
                .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
    }
}

